package io.xxx.xbutler.core.select.receiver;

import io.xxx.xbutler.domain.Contact;
import io.xxx.xbutler.domain.Room;
import io.xxx.xbutler.domain.SelectMode;
import io.xxx.xbutler.domain.task.Receiver;
import io.xxx.xbutler.domain.task.ReceiverType;
import io.xxx.xbutler.domain.task.Task;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cursor.Cursor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import reactor.core.publisher.Flux;

@Slf4j
@Component
public class AreaReceiverSelector extends AbstractReceiverSelector {

    @Resource
    private TransactionTemplate transactionTemplate;

    @Override
    public Flux<Receiver> select(Task task) {
        ReceiverType receiverType = task.getReceiverType();
        return Flux.create(emitter ->
                transactionTemplate.executeWithoutResult(_ -> {
                    try {
                        switch (receiverType) {
                            case CONTACT: {
                                Cursor<Contact> cursor = contactMapper.selectCursorByArea(task.getAreaId(), task.getOperateAreaId());
                                try (cursor) {
                                    for (Contact contact : cursor) {
                                        Receiver receiver = buildReceiver(contact);
                                        emitter.next(receiver);
                                    }
                                }
                                break;
                            }
                            case ROOM: {
                                Cursor<Room> cursor = roomMapper.selectCursorByArea(task.getAreaId(), task.getOperateAreaId());
                                try (cursor) {
                                    for (Room room : cursor) {
                                        Receiver receiver = buildReceiver(room);
                                        emitter.next(receiver);
                                    }
                                }
                                break;
                            }
                        }
                        emitter.complete();
                    } catch (Exception e) {
                        log.error("查询数据库异常[taskId:{}, areaId:{}, operateAreaId:{}]", task.getId(), task.getAreaId(), task.getOperateAreaId(), e);
                        emitter.error(e);
                    }
                }));
    }

    @Override
    public boolean supports(SelectMode selectMode) {
        return selectMode == SelectMode.AREA;
    }
}
